package test;


import java.util.Vector;

import junit.framework.TestCase;


import org.junit.Test;
import Auxiliary.Sequence_CondReact;
import Auxiliary.Sequence_Event;
import Auxiliary.Sequence_Row;
import Auxiliary.Sequence_State;
import Auxiliary.Sequence_StateObserver;
import Auxiliary.Sequence_Value;
import DataView.Action;
import DataView.AttributeInfo;
import DataView.ClassDiagramInfo;
import DataView.ClassInfo;
import DataView.CondReactInfo;
import DataView.Expr;
import DataView.OperationInfo;
import DataView.ParameterInfo;
import DataView.StateObserverInfo;
import Store.Attribute;
import Store.Class;
import Store.ClassDiagram;
import Store.CondReact;
import Store.Enumeration;
import Store.Event;
import Store.Operation;
import Store.Parameter;
import Store.Row;
import Store.State;
import Store.StateObserver;
import Store.StateTable;
import Store.Transition;
import Store.Type;
import calculator.Generator;

public class testClass extends TestCase
{


	@Test
	public void testGenerateST_IsNotNull()   
	{
		
		StateObserver so1 = new StateObserver();
		//a mkelement di stateObserver serve una StateObserverInfo
		StateObserverInfo SOI1 = new StateObserverInfo();
		//a setInfo di StateObserverInfo serve (String text, Type t, null)
		String s1 = "Info1";
		Type t1 = Type.boolean_();
		SOI1.setInfo(s1, t1, null);
		so1.mkElement(SOI1);
		
		
		StateObserver so2 = new StateObserver();
		//a mkelement di stateObserver serve una StateObserverInfo
		StateObserverInfo SOI2 = new StateObserverInfo();
		//a setInfo di StateObserverInfo serve (String text, Type t, null)
		String s2 = "Info2";
		Type t2 = Type.boolean_();
		SOI2.setInfo(s2, t2, null);
		so2.mkElement(SOI2);
		
		
		
		Sequence_StateObserver seq = new Sequence_StateObserver();
		//aggiungo i vari stateObserver alla seq
		seq.add(so1);
		seq.add(so2);
		
		//serve passare una Sequence_StateObserver
		Sequence_Row sr = Generator.generateST(seq);	
		
		
		assertNotNull(sr);
		
	}
	
	
	@Test
	public void testGenerateST_SizeAndElements() 
	{
		StateObserver so1 = new StateObserver();
		StateObserverInfo SOI1 = new StateObserverInfo();
		String s1 = "Info1";
		Type t1 = Type.boolean_();
		SOI1.setInfo(s1, t1, null);
		so1.mkElement(SOI1);
		
		
		StateObserver so2 = new StateObserver();
		StateObserverInfo SOI2 = new StateObserverInfo();
		String s2 = "Info2";
		Type t2 = Type.boolean_();
		SOI2.setInfo(s2, t2, null);
		so2.mkElement(SOI2);
		
		
		Sequence_StateObserver seq = new Sequence_StateObserver();
		seq.add(so1);
		seq.add(so2);
		
		
		Sequence_Row sr = Generator.generateST(seq);	
		
		
		assertEquals(4, sr.size());
		
		assertEquals(sr.get(0).getValues().get(0).getName(), "true");
		assertEquals(sr.get(0).getValues().get(1).getName(), "true");
		
		assertEquals(sr.get(1).getValues().get(0).getName(), "true");
		assertEquals(sr.get(1).getValues().get(1).getName(), "false");
		
		assertEquals(sr.get(2).getValues().get(0).getName(), "false");
		assertEquals(sr.get(2).getValues().get(1).getName(), "true");
		
		assertEquals(sr.get(3).getValues().get(0).getName(), "false");
		assertEquals(sr.get(3).getValues().get(1).getName(), "false");
	
			
	}
	

	@Test
	public void testGenerateBasicSO_IsNotNull()
	{
		
		Class c = new Class();
		
		//a mkelement di Class serve un classInfo
		ClassInfo ci = new ClassInfo();
		//a setInfo di ClassInfo serve: ((String name, Vector<Operation> operazioni, Vector<Attribute> attributi))
		String s = "ClassInfo1";
		Operation op1 = new Operation();
		//a mkElement di operation serve un OperationInfo
		OperationInfo opI1 = new OperationInfo();
		//a setInfo di OperationInfo serve (String s, null, null, Type t)
		String s2 = "OperationInfo1";
		Type t1 = Type.integer();
		opI1.setInfo(s2, null, null, t1);
		Operation op2 = new Operation();
		//a mkElement di operation serve un OperationInfo
		OperationInfo opI2 = new OperationInfo();
		//a setInfo di OperationInfo serve (String s, null, null, Type t)
		String s3 = "OperationInfo2";
		Type t2 = Type.boolean_();
		opI2.setInfo(s3, null, null, t2);
		op1.mkElement(opI1);
		op2.mkElement(opI2);
		
		Vector<Operation> v = new Vector<Operation>();
		v.add(op1);
		v.add(op2);
		
		Attribute a1 = new Attribute();
		//a mkelement di attribute serve un attributeinfo
		AttributeInfo att1 = new AttributeInfo();
		//a setInfo di attributeinfo serve (String name, null, Type type)
		String s4 = "attInfo1";
		Type t3 = Type.real();
		att1.setInfo(s4, null, t3);
		a1.mkElement(att1);
		
		Attribute a2 = new Attribute();
		//a mkelement di attribute serve un attributeinfo
		AttributeInfo att2 = new AttributeInfo();
		//a setInfo di attributeinfo serve (String name, null, Type type)
		String s5 = "attInfo2";
		Type t4 = Type.boolean_();
		att2.setInfo(s5, null, t4);
		a2.mkElement(att2);
		
		Vector<Attribute> v1 = new Vector<Attribute>();
		v1.add(a1);
		v1.add(a2);
		
		ci.setInfo(s, v, v1);
		c.mkElement(ci);
		
		
		//creo la sequence
		Sequence_StateObserver l = Generator.generateBasicSO(null, c);
		
		assertNotNull(l);
		
	}
	
	
	@Test
	public void testGenerateBasicSO_SizeAndElements()
	{
		
		
		Class c = new Class();
		
		ClassInfo ci = new ClassInfo();
		String s = "ClassInfo1";
		Operation op1 = new Operation();
		OperationInfo opI1 = new OperationInfo();
		String s2 = "OperationInfo1";
		Type t1 = Type.integer();
		opI1.setInfo(s2, null, null, t1);
		Operation op2 = new Operation();
		OperationInfo opI2 = new OperationInfo();
		String s3 = "OperationInfo2";
		Type t2 = Type.boolean_();
		opI2.setInfo(s3, null, null, t2);
		op1.mkElement(opI1);
		op2.mkElement(opI2);
		
		Vector<Operation> v = new Vector<Operation>();
		v.add(op1);
		v.add(op2);
		
		Attribute a1 = new Attribute();
		AttributeInfo att1 = new AttributeInfo();
		String s4 = "attInfo1";
		Type t3 = Type.real();
		att1.setInfo(s4, null, t3);
		a1.mkElement(att1);
		
		Attribute a2 = new Attribute();
		AttributeInfo att2 = new AttributeInfo();
		String s5 = "attInfo2";
		Type t4 = Type.boolean_();
		att2.setInfo(s5, null, t4);
		a2.mkElement(att2);
		
		Vector<Attribute> v1 = new Vector<Attribute>();
		v1.add(a1);
		v1.add(a2);
		
		ci.setInfo(s, v, v1);
		c.mkElement(ci);
		
		
		Sequence_StateObserver l = Generator.generateBasicSO(null, c);
		
		//size deve essere 2,devono esserci solamente i due attributes e non le 2 operations
		assertEquals(l.size(), 2);
		
		assertEquals(l.get(0).getName(), "attInfo1");
		assertEquals(l.get(0).getType().getName(), "real");
		assertEquals(l.get(1).getName(), "attInfo2");
		assertEquals(l.get(1).getType().getName(), "boolean");
		
	}

	
	@Test
	public void testGenerateBasicEV_IsNotNull()	  
	{
			
		Class c = new Class();
		//a mkElement di class serve (ClassInfo myInfo)
		ClassInfo classInfo1 = new ClassInfo();
		//a setInfo di classInfo serve (String name, Vector<Operation> operazioni, Vector<Attribute> attributi)
		//STRING 
		String name = "classInfo1";
		
		//VECTOR<OPERATION>
		Vector<Operation> v_operation1 = new Vector<Operation>();
		Operation op1 = new Operation();
		//a mkElement di operation serve (OperationInfo aElIN)
		OperationInfo Oper_info1 = new OperationInfo();
		//a setInfo di operationInfo serve (String s, Class c(null), Vector<Parameter> pars, Type t)
		String OpInfo1_name = "operationInfo1";
		Vector<Parameter> v_param1 = new Vector<Parameter>();
		Parameter p1 = new Parameter();
		// a mkElement di parameter serve (ParameterInfo aElIN)
		ParameterInfo param_info1 = new ParameterInfo();
		//a setInfo di parameterinfo serve (String s, Type t)
		String param_info1_name = "parameter_info1";
		Type t1 = Type.boolean_();
		param_info1.setInfo(param_info1_name, t1);
		p1.mkElement(param_info1);
		v_param1.add(p1);
		Type t2 = Type.boolean_();
		Oper_info1.setInfo(OpInfo1_name, null, v_param1, t2);
		op1.mkElement(Oper_info1);
		v_operation1.add(op1);
		
		
		//VECTOR<ATTRIBUTE>
		Vector<Attribute> v_attr1 = new Vector<Attribute>();
		Attribute a1 = new Attribute();
		//a mkelement di attribute serve un attributeinfo
		AttributeInfo att1 = new AttributeInfo();
		//a setInfo di attributeinfo serve (String name, null, Type type)
		String attr_info_name = "attInfo1";
		Type t3 = Type.real();
		att1.setInfo(attr_info_name, null, t3);
		a1.mkElement(att1);
		v_attr1.add(a1);
		
		classInfo1.setInfo(name, v_operation1, v_attr1);
		c.mkElement(classInfo1);
		
		
		//(dalle operation passate vengono creati gli eventi)
		Sequence_Event seq = Generator.generateBasicEV(null, c);		
		assertNotNull(seq);
		
	}
	
	
	
	@Test
	public void testGenerateBasicEV_SizeAndElements()	
	{
		Class c = new Class();
		ClassInfo classInfo1 = new ClassInfo();
		
		String name = "classInfo1";
		
		Vector<Operation> v_operation1 = new Vector<Operation>();
		Operation op1 = new Operation();
		OperationInfo Oper_info1 = new OperationInfo();
		String OpInfo1_name = "operationInfo1";
		Vector<Parameter> v_param1 = new Vector<Parameter>();
		Parameter p1 = new Parameter();
		ParameterInfo param_info1 = new ParameterInfo();
		String param_info1_name = "parameter_info1";
		Type t1 = Type.boolean_();
		param_info1.setInfo(param_info1_name, t1);
		p1.mkElement(param_info1);
		v_param1.add(p1);
		Type t2 = Type.boolean_();
		Oper_info1.setInfo(OpInfo1_name, null, v_param1, t2);
		op1.mkElement(Oper_info1);
		v_operation1.add(op1);
		
		
		Vector<Attribute> v_attr1 = new Vector<Attribute>();
		Attribute a1 = new Attribute();
		AttributeInfo att1 = new AttributeInfo();
		String attr_info_name = "attInfo1";
		Type t3 = Type.real();
		att1.setInfo(attr_info_name, null, t3);
		a1.mkElement(att1);
		v_attr1.add(a1);
		
		classInfo1.setInfo(name, v_operation1, v_attr1);
		c.mkElement(classInfo1);
		
		
		Sequence_Event seq = Generator.generateBasicEV(null, c);
		
		assertEquals(1, seq.size());
		assertEquals("operationInfo1", seq.get(0).getInfo().getName());
		assertEquals(seq.get(0).getInfo().getParameters().get(0).getInfo().getName(), "parameter_info1");
		assertEquals(seq.get(0).getInfo().getParameters().get(0).getInfo().getType().getName(), "boolean");
		
	}
	
	

	
	@Test
	public void testGenerateStates_No_States_Added() 
	{
		
		Sequence_StateObserver seq_SO = new Sequence_StateObserver();
		
		//creo due so 
		String name1 = "first";
		Type t1 = Type.boolean_();
		Expr exp1 = new Expr("expr1");
		StateObserver so1 = new StateObserver(name1, t1, exp1);
		//a mkelement di stateobserver serve un (StateObserverInfo ei) 
		StateObserverInfo so1Info = new StateObserverInfo();
		//a setInfo di stateobserverinfo serve (String text, Type t, Expr exp)
		String Info1 = "Info1";
		Type t2 = Type.boolean_();
		Expr exp2 = new Expr("expr2");
		so1Info.setInfo(Info1, t2, exp2);
		so1.mkElement(so1Info);
		
		
		String name2 = "second";
		Type t3 = Type.boolean_();
		Expr exp3 = new Expr("expr3");
		StateObserver so2 = new StateObserver(name2, t3, exp3);
		//a mkelement di stateobserver serve un (StateObserverInfo ei) 
		StateObserverInfo so2Info = new StateObserverInfo();
		//a setInfo di stateobserverinfo serve (String text, Type t, Expr exp)
		String Info2 = "Info2";
		Type t4 = Type.boolean_();
		Expr exp4 = new Expr("expr4");
		so2Info.setInfo(Info2, t4, exp4);
		so2.mkElement(so2Info);
		
		seq_SO.add(so1);
		seq_SO.add(so2);
		
		
		//genero la sequence_row
		Sequence_Row seq_row = Generator.generateST(seq_SO);
		//da 2 so crea 4 rows nella sequence_row
		
		
		//creo stateTable con le 2 sequence ottenute
		StateTable st = new StateTable();
		st.setUsedSO(seq_SO);
		st.setROW(seq_row);
		
		
		//creo la seq_states
		Sequence_State seq_state = Generator.generateStates(st);
		assertEquals(0, seq_state.size());	//sono tutti impossible e non ci vanno
		
	}

	
	@Test
	public void testGenerateStates_Three_States_Added()
	{
		
		Sequence_StateObserver seq_SO = new Sequence_StateObserver();
		
		
		
		String name1 = "first";
		Type t1 = Type.boolean_();
		Expr exp1 = new Expr("expr1");
		StateObserver so1 = new StateObserver(name1, t1, exp1);
		StateObserverInfo so1Info = new StateObserverInfo();
		String Info1 = "Info1";
		Type t2 = Type.boolean_();
		Expr exp2 = new Expr("expr2");
		so1Info.setInfo(Info1, t2, exp2);
		so1.mkElement(so1Info);
		
		
		String name2 = "second";
		Type t3 = Type.boolean_();
		Expr exp3 = new Expr("expr3");
		StateObserver so2 = new StateObserver(name2, t3, exp3);
		StateObserverInfo so2Info = new StateObserverInfo();
		String Info2 = "Info2";
		Type t4 = Type.boolean_();
		Expr exp4 = new Expr("expr4");
		so2Info.setInfo(Info2, t4, exp4);
		so2.mkElement(so2Info);
		
		seq_SO.add(so1);
		seq_SO.add(so2);
		
		
		Sequence_Row seq_row = Generator.generateST(seq_SO);
		
		
		StateTable st = new StateTable();
		st.setUsedSO(seq_SO);
		st.setROW(seq_row);
		
		
		//cambio stati
		st.defineState(st.getRow(0), "one");
		st.defineState(st.getRow(1), "two");	
		st.defineState(st.getRow(2), "three");
		
		
		//creo la seq_states
		Sequence_State seq_state = Generator.generateStates(st);
		//controlla che ci siano i nuovi 3 stati
		assertEquals(3, seq_state.size());
		
		
		//verifico gli stati
		assertEquals("one", st.getRow(0).getState().getName());
		assertEquals("two", st.getRow(1).getState().getName());
		assertEquals("three", st.getRow(2).getState().getName());
		
		
	}
	
	

	@Test
	public void testGenerateOutputCD() 
	{
		
		//a generate_outputcd serve (ClassDiagram aIcd, Sequence_StateObserver aSos, Sequence_Event aEvs)
		
		ClassDiagram cd = new ClassDiagram();
		//a mkElement di classDiagram serve classdiagraminfo
		ClassDiagramInfo cdInfo = new ClassDiagramInfo();
		//a setInfo di classdiagraminfo serve (Class context, null, null)
		
		Class context = new Class();
		//a mkElement di class serve (ClassInfo myInfo)
		ClassInfo contextInfo = new ClassInfo();
		// a setInfo di classInfo serve (String name, Vector<Operation> operazioni, Vector<Attribute> attributi)
		String name = "contextInfo";
		
		Vector<Operation> v_operation1 = new Vector<Operation>();
		Operation op1 = new Operation();
		OperationInfo Oper_info1 = new OperationInfo();
		String OpInfo1_name = "operationInfo1";
		Vector<Parameter> v_param1 = new Vector<Parameter>();
		Parameter p1 = new Parameter();
		ParameterInfo param_info1 = new ParameterInfo();
		String param_info1_name = "parameter_info1";
		Type t1 = Type.boolean_();
		param_info1.setInfo(param_info1_name, t1);
		p1.mkElement(param_info1);
		v_param1.add(p1);
		Type t2 = Type.boolean_();
		Oper_info1.setInfo(OpInfo1_name, null, v_param1, t2);
		op1.mkElement(Oper_info1);
		v_operation1.add(op1);
		
		Vector<Attribute> v_attr1 = new Vector<Attribute>();
		Attribute a1 = new Attribute();
		AttributeInfo att1 = new AttributeInfo();
		String attr_info_name = "attInfo1";
		Type t3 = Type.real();
		att1.setInfo(attr_info_name, null, t3);
		a1.mkElement(att1);
		v_attr1.add(a1);
		
		contextInfo.setInfo(name, v_operation1, v_attr1);
		context.mkElement(contextInfo);
		Vector<Class> v_class = new Vector<Class>();
		v_class.add(context);
		cdInfo.setInfo(context, v_class, new Vector<Enumeration>());
		cd.mkElement(cdInfo);
		
		
		Sequence_StateObserver seq_so = Generator.generateBasicSO(cd, context);	
		
		StateObserver so1 = new StateObserver();
		//a mkelement di stateobserver serve un (StateObserverInfo ei) 
		StateObserverInfo so1Info = new StateObserverInfo();
		//a setInfo di stateobserverinfo serve (String text, Type t, Expr exp)
		String Info1 = "Info1";
		Type t4 = Type.boolean_();
		Expr exp2 = new Expr("expr2");
		so1Info.setInfo(Info1, t4, exp2);
		so1.mkElement(so1Info);
		
		seq_so.add(so1);
		
		
		Sequence_Event seq_ev = Generator.generateBasicEV(cd, context);
		
		
		
		//a mkElement serve (String name, Vector<Parameter> vector, Sequence_CondReact cr)
		String ev_name = "e";
		
		Vector<Parameter> v_param = new Vector<Parameter>();
		Parameter p2 = new Parameter();
		//a mkelement serve (ParameterInfo aElIN)
		ParameterInfo p2Info = new ParameterInfo();
		//a setinfo serve (String s, Type t)
		String p2InfoName = "p2Info";
		Type t5 = Type.boolean_();
		p2Info.setInfo(p2InfoName, t5);
		p2.mkElement(p2Info);
		v_param.add(p2);
		
		Sequence_CondReact seq_cr = new Sequence_CondReact();
		CondReact cr1 = new CondReact();
		//a mkelement serve (CondReactInfo aNewCR)
		CondReactInfo cr1Info = new CondReactInfo();
		//a setinfo serve (Expr acond, Action areact)
		Expr exp3 = new Expr("exp3");
		Action a2 = new Action("a2");
		cr1Info.setInfo(exp3, a2);
		cr1.mkElement(cr1Info);
		seq_cr.add(cr1);
		
		
		Event e = new Event(ev_name, v_param, seq_cr);
		
		seq_ev.add(e);
		
		ClassDiagram outCD = Generator.generateOutputCD(cd, seq_so, seq_ev);
		
		assertEquals(2, outCD.context().getInfo().list_Operation.size());
		assertEquals(2, outCD.context().getInfo().list_Attribute.size());
	
	}
	
	@Test
	public void test_generateTransition()
	{
		String name = "e";
		Sequence_CondReact seq_cr = new Sequence_CondReact();
		//creo una cond-react
		CondReact cr = new CondReact();
		//a mkelement serve (CondReactInfo aNewCR)
		CondReactInfo crInfo = new CondReactInfo();
		//a setInfo serve (Expr acond, Action areact)
		Expr exp = new Expr("exp");
		Action a = new Action("a");
		crInfo.setInfo(exp, a);
		cr.mkElement(crInfo);
		//setto i campi cond rest e reac rest
		cr.setSplit(null, exp, null, a);
		seq_cr.add(cr);
		
		
		Event e = new Event(name, new Vector<Parameter>(), seq_cr);
		
		State s = new State();
		//a setinfo serve (String n , boolean isfinal, boolean isinitial)
		s.setInfo("s", false, true);
		
		Row r = new Row();
		//a setinfo serve (Sequence_Value v, String n, State s)
		String rowName = "r";
		State s2 = new State();
		s2.setInfo("s2", true, false);
		r.setInfo(new Sequence_Value(), rowName, s2);
		
		
		Transition t = Generator.generateTransition(s, e, e.getInfo().getCondReact().get(0), r);
		
		assertEquals(t.getSource(), s);
		assertEquals(t.getTrigger(), e.getNameDes());
		assertEquals(t.getCond(), cr.getCond());
		assertEquals(t.getReact(), cr.getReact());
		assertEquals(t.getTarget(), r.getState());
		
	}
	
}
